From: Keir Fraser Date: Thu, 22 Jan 2009 11:21:43 +0000 (+0000) Subject: vmx: utilise the GUEST_PAT and HOST_PAT vmcs area X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14014^2~32 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=a2430522fd37d31312638c840aade27e4439216e;p=xen.git vmx: utilise the GUEST_PAT and HOST_PAT vmcs area Signed-off-by: Xin Li Signed-off-by: Xiaohui Xin --- diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 4fd560dece..c86b55e6f7 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -167,14 +167,15 @@ static void vmx_init_vmcs_config(void) #endif min = VM_EXIT_ACK_INTR_ON_EXIT; - opt = 0; + opt = VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_LOAD_HOST_PAT; #ifdef __x86_64__ min |= VM_EXIT_IA32E_MODE; #endif _vmx_vmexit_control = adjust_vmx_controls( min, opt, MSR_IA32_VMX_EXIT_CTLS); - min = opt = 0; + min = 0; + opt = VM_ENTRY_LOAD_GUEST_PAT; _vmx_vmentry_control = adjust_vmx_controls( min, opt, MSR_IA32_VMX_ENTRY_CTLS); @@ -519,8 +520,6 @@ static int construct_vmcs(struct vcpu *v) /* VMCS controls. */ __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control); - __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control); - __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control); v->arch.hvm_vmx.exec_control = vmx_cpu_based_exec_control; v->arch.hvm_vmx.secondary_exec_control = vmx_secondary_exec_control; @@ -534,12 +533,18 @@ static int construct_vmcs(struct vcpu *v) else { v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; + vmx_vmexit_control &= ~(VM_EXIT_SAVE_GUEST_PAT | + VM_EXIT_LOAD_HOST_PAT); + vmx_vmentry_control &= ~VM_ENTRY_LOAD_GUEST_PAT; } /* Do not enable Monitor Trap Flag unless start single step debug */ v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG; __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); + __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control); + __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control); + if ( cpu_has_vmx_secondary_exec_control ) __vmwrite(SECONDARY_VM_EXEC_CONTROL, v->arch.hvm_vmx.secondary_exec_control); @@ -561,6 +566,8 @@ static int construct_vmcs(struct vcpu *v) vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_CS); vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_ESP); vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_EIP); + if ( cpu_has_vmx_pat && paging_mode_hap(d) ) + vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT); } /* I/O access bitmap. */ @@ -692,6 +699,21 @@ static int construct_vmcs(struct vcpu *v) __vmwrite(VIRTUAL_PROCESSOR_ID, v->arch.hvm_vmx.vpid); } + if ( cpu_has_vmx_pat && paging_mode_hap(d) ) + { + u64 host_pat, guest_pat; + + rdmsrl(MSR_IA32_CR_PAT, host_pat); + guest_pat = 0x7040600070406ULL; + + __vmwrite(HOST_PAT, host_pat); + __vmwrite(GUEST_PAT, guest_pat); +#ifdef __i386__ + __vmwrite(HOST_PAT_HIGH, host_pat >> 32); + __vmwrite(GUEST_PAT_HIGH, guest_pat >> 32); +#endif + } + vmx_vmcs_exit(v); paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */ @@ -989,6 +1011,8 @@ void vmcs_dump_vcpu(struct vcpu *v) vmx_dump_sel("LDTR", GUEST_LDTR_SELECTOR); vmx_dump_sel2("IDTR", GUEST_IDTR_LIMIT); vmx_dump_sel("TR", GUEST_TR_SELECTOR); + printk("Guest PAT = 0x%08x%08x\n", + (uint32_t)vmr(GUEST_PAT_HIGH), (uint32_t)vmr(GUEST_PAT)); x = (unsigned long long)vmr(TSC_OFFSET_HIGH) << 32; x |= (uint32_t)vmr(TSC_OFFSET); printk("TSC Offset = %016llx\n", x); @@ -1027,6 +1051,8 @@ void vmcs_dump_vcpu(struct vcpu *v) (unsigned long long)vmr(HOST_SYSENTER_ESP), (int)vmr(HOST_SYSENTER_CS), (unsigned long long)vmr(HOST_SYSENTER_EIP)); + printk("Host PAT = 0x%08x%08x\n", + (uint32_t)vmr(HOST_PAT_HIGH), (uint32_t)vmr(HOST_PAT)); printk("*** Control State ***\n"); printk("PinBased=%08x CPUBased=%08x SecondaryExec=%08x\n", diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h index 5337ec93dd..80640e0d5a 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -156,11 +156,14 @@ extern u32 vmx_pin_based_exec_control; #define VM_EXIT_IA32E_MODE 0x00000200 #define VM_EXIT_ACK_INTR_ON_EXIT 0x00008000 +#define VM_EXIT_SAVE_GUEST_PAT 0x00040000 +#define VM_EXIT_LOAD_HOST_PAT 0x00080000 extern u32 vmx_vmexit_control; #define VM_ENTRY_IA32E_MODE 0x00000200 #define VM_ENTRY_SMM 0x00000400 #define VM_ENTRY_DEACT_DUAL_MONITOR 0x00000800 +#define VM_ENTRY_LOAD_GUEST_PAT 0x00004000 extern u32 vmx_vmentry_control; #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 @@ -189,6 +192,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr_info; (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID) #define cpu_has_monitor_trap_flag \ (vmx_cpu_based_exec_control & CPU_BASED_MONITOR_TRAP_FLAG) +#define cpu_has_vmx_pat \ + (vmx_vmentry_control & VM_ENTRY_LOAD_GUEST_PAT) /* GUEST_INTERRUPTIBILITY_INFO flags. */ #define VMX_INTR_SHADOW_STI 0x00000001 @@ -240,6 +245,8 @@ enum vmcs_field { VMCS_LINK_POINTER_HIGH = 0x00002801, GUEST_IA32_DEBUGCTL = 0x00002802, GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, + GUEST_PAT = 0x00002804, + GUEST_PAT_HIGH = 0x00002805, GUEST_PDPTR0 = 0x0000280a, GUEST_PDPTR0_HIGH = 0x0000280b, GUEST_PDPTR1 = 0x0000280c, @@ -248,6 +255,8 @@ enum vmcs_field { GUEST_PDPTR2_HIGH = 0x0000280f, GUEST_PDPTR3 = 0x00002810, GUEST_PDPTR3_HIGH = 0x00002811, + HOST_PAT = 0x00002c00, + HOST_PAT_HIGH = 0x00002c01, PIN_BASED_VM_EXEC_CONTROL = 0x00004000, CPU_BASED_VM_EXEC_CONTROL = 0x00004002, EXCEPTION_BITMAP = 0x00004004,